<?php
/**
 * Created by PhpStorm.
 *
 * @Date: 2017-08-08
 * @Time: 09:54
 * @Author: cdkay
 * @Email: network@iyuanma.net
 *
 * @File： v163SMS.php
 */

namespace library;

use think\Config;
use think\Log;

/**
 * Class ServerAPI
 * @package library
 */
final class ServerAPI{
    private $AppKey;
    private $AppSecret;
    private $Nonce; //随机数（最大长度128个字符）
    private $CurTime; //当前UTC时间戳，从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
    private $CheckSum;//SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串，进行SHA1哈希计算，转化成16进制字符(String，小写)

    const   HEX_DIGITS = "0123456789abcdef";

    const   URL = 'https://api.netease.im';

    const TEMPLATE_LIVE_SUBSCRIBE_NOTICE = '3095014';
    const TEMPLATE_LIVE_OPEN_REMIND = '3101007';
    const TEMPLATE_BUY_SUCCESS = '3090061';

    private static $instance = null;
    public static function getInstance(): ServerAPI {
        if (empty(self::$instance)) {
            self::$instance = new ServerAPI(
                config('v163SMS.appKey'),
                config('v163SMS.appSecret')
            );
        }
        return self::$instance;
    }

    /**
     * 参数初始化
     * @param $AppKey
     * @param $AppSecret
     * @param $RequestType [选择php请求方式，fsockopen或curl,若为curl方式，请检查php配置是否开启]
     */
    private function __construct($AppKey,$AppSecret,$RequestType='curl'){
        $this->AppKey    = $AppKey;
        $this->AppSecret = $AppSecret;
        $this->RequestType = $RequestType;
    }

    /**
     * API checksum校验生成
     */
    public function checkSumBuilder(){
        //此部分生成随机字符串
        $hex_digits = self::HEX_DIGITS;
        $this->Nonce;
        for($i=0;$i<128;$i++){          //随机字符串最大128个字符，也可以小于该数
            $this->Nonce.= $hex_digits[rand(0,15)];
        }
        $this->CurTime = (string)(time());  //当前时间戳，以秒为单位

        $join_string = $this->AppSecret.$this->Nonce.$this->CurTime;
        $this->CheckSum = sha1($join_string);
    }


    /**
     * 使用CURL方式发送post请求
     * @param string $url     [请求地址]
     * @param mixed $data    [array格式数据]
     * @return $请求返回结果(array)
     */
    public function postDataCurl($url,$data){

        $url = self::URL . $url;

        $this->checkSumBuilder();//发送请求前需先生成checkSum

        $timeout = 5000;
        $http_header = array(
            'AppKey:'.$this->AppKey,
            'Nonce:'.$this->Nonce,
            'CurTime:'.$this->CurTime,
            'CheckSum:'.$this->CheckSum,
            'Content-Type:application/x-www-form-urlencoded;charset=utf-8'
        );

        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_POST, 1);
        curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt ($ch, CURLOPT_HEADER, false );
        curl_setopt ($ch, CURLOPT_HTTPHEADER,$http_header);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER,false); //处理http证书问题
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($ch);

        $errNo = curl_errno($ch);
        $errMsg = curl_error($ch);
        curl_close($ch);
        if ($errNo) {
            Log::error("$errNo: $errMsg");
            return null;
        }

        return json_decode($result,true);
    }

    /**
     * sendSMSCode
     * 发送短信验证码
     *
     * @author zhengkai
     * @date 2017-08-08
     *
     * @param string $mobile 手机号码
     * @param int $codeLength
     * @return array
     */
    public function sendCode($mobile='', $codeLength = 4){
        $url = '/sms/sendcode.action';
        $data  = array(
            'mobile'=> $mobile, // 手机号码
            'deviceId'=>'', // 目标设置号
            'templateid'=>'3064923', // 模板id
            'codeLen'=> $codeLength // 验证码长度s
        );

        return $this->postDataCurl($url, $data);
    }

    /**
     * verifyCode
     * 短信验证码验证
     *
     * @author zhengkai
     * @date 2017-08-08
     *
     * @param string $mobile 手机号码
     * @param string $Code 验证码
     * @return array
     */
    public function verifyCode($mobile='', $Code=''){
        $url = '/sms/verifycode.action';
        $data  = array(
            'mobile'=> $mobile,
            'code' => $Code,
        );

        return $this->postDataCurl($url, $data);
    }

    /**
     * 通知短信发送
     *
     * @author zhengkai
     * @date 2017-09-14
     *
     * @param string $templateId 模板编号
     * @param array $mobiles 短信参数列表，用于依次填充模板，JSONArray格式，每个变量长度不能超过30字，如["xxx","yyy"];对于不包含变量的模板，不填此参数表示模板即短信全文内容
     * @param array $params 接收者号码列表，JSONArray格式,如["186xxxxxxxx","186xxxxxxxx"]，限制接收者号码个数最多为100个
     * @return array
     */
    public function sendMessage($templateId, $mobiles=[], $params=[]){
        $url = '/sms/sendtemplate.action';
        $data  = array(
            'templateid' => $templateId,
            'mobiles' => json_encode($mobiles),
            'params' => json_encode($params)
        );

        return $this->postDataCurl($url,$data);
    }
}